package com.googlecode.textish.format;

import java.io.IOException;
import java.io.Writer;

import com.googlecode.textish.parser.ContainerTokenDecorator;
import com.googlecode.textish.parser.TextishParser;
import com.googlecode.textish.tokenizer.DocumentToken;

/**
 * Used from within the {@link TextishParser} class to produce output from a
 * token tree.
 * 
 * @author cgdavies
 * 
 */
public interface IFormatter {

	/**
	 * Called before a {@link DocumentToken} is parsed.
	 * 
	 * @param context the original text that the tokens were built from
	 * @param document the wrapped {@link DocumentToken}
	 * @param output the output destination
	 * @return <code>true</code> if further parsing of this level and
	 * sublevels should continue
	 * @throws IOException
	 */
	public boolean beforeDocument(CharSequence context, ContainerTokenDecorator document, Writer output)
			throws IOException;

	/**
	 * Called after a {@link DocumentToken} is parsed.
	 * 
	 * @param context the original text that the tokens were built from
	 * @param document the wrapped {@link DocumentToken}
	 * @param output the output destination
	 * @return <code>true</code> if further parsing of this level should
	 * continue
	 * @throws IOException
	 */
	public boolean afterDocument(CharSequence context, ContainerTokenDecorator document, Writer output)
			throws IOException;

	/**
	 * Called before a {@link ParagraphToken} is parsed.
	 * 
	 * @param context the original text that the tokens were built from
	 * @param document the wrapped {@link ParagraphToken}
	 * @param output the output destination
	 * @return <code>true</code> if further parsing of this level and
	 * sublevels should continue
	 * @throws IOException
	 */
	public boolean beforeParagraph(CharSequence context, ContainerTokenDecorator paragraph, Writer output)
			throws IOException;

	/**
	 * Called after a {@link ParagraphToken} is parsed.
	 * 
	 * @param context the original text that the tokens were built from
	 * @param document the wrapped {@link ParagraphToken}
	 * @param output the output destination
	 * @return <code>true</code> if further parsing of this level should
	 * continue
	 * @throws IOException
	 */
	public boolean afterParagraph(CharSequence context, ContainerTokenDecorator paragraph, Writer output)
			throws IOException;

	/**
	 * Called before a {@link LineToken} is parsed.
	 * 
	 * @param context the original text that the tokens were built from
	 * @param document the wrapped {@link LineToken}
	 * @param output the output destination
	 * @return <code>true</code> if further parsing of this level and
	 * sublevels should continue
	 * @throws IOException
	 */
	public boolean beforeLine(CharSequence context, ContainerTokenDecorator line, Writer output) throws IOException;

	/**
	 * Called after a {@link LineToken} is parsed.
	 * 
	 * @param context the original text that the tokens were built from
	 * @param document the wrapped {@link LineToken}
	 * @param output the output destination
	 * @return <code>true</code> if further parsing of this level should
	 * continue
	 * @throws IOException
	 */
	public boolean afterLine(CharSequence context, ContainerTokenDecorator line, Writer output) throws IOException;

	/**
	 * Called before a {@link WordToken} is parsed.
	 * 
	 * @param context the original text that the tokens were built from
	 * @param document the wrapped {@link WordToken}
	 * @param output the output destination
	 * @return <code>true</code> if further parsing of this level and
	 * sublevels should continue
	 * @throws IOException
	 */
	public boolean beforeWord(CharSequence context, ContainerTokenDecorator word, Writer output) throws IOException;

	/**
	 * Called after a {@link WordToken} is parsed.
	 * 
	 * @param context the original text that the tokens were built from
	 * @param document the wrapped {@link WordToken}
	 * @param output the output destination
	 * @return <code>true</code> if further parsing of this level should
	 * continue
	 * @throws IOException
	 */
	public boolean afterWord(CharSequence context, ContainerTokenDecorator word, Writer output) throws IOException;
}
